<template>
    <div id="app">
        <canvas :style="`width:${WIDTH}px;height:${HEIGHT}px;`" ref="canvas"></canvas>
        <!--

        <nav>
            <a v-for="part, index in parts" :key="index" :class="`${part.selected ? 'Selected' : ''}`">
                <h2>{{ part.name }}</h2>
                <h3 v-if="part.selectIndex != null">({{ part.selectIndex + 1 }}/{{ part.items.length }})</h3>
                <h3 v-else>(共{{ part.items.length }}款)</h3>
            </a>
        </nav>


        <section>

        </section>
        -->
    </div>
</template>
<style scoped>
#app {
    display: flex;
    flex-direction: column;
    background: #003;
    height: 100%;
}

canvas {
    background: blue;
}

nav {
    flex-wrap: nowrap;
    overflow-x: scroll;
    white-space: nowrap;
    border: 1px solid cyan;
    border-width: 1px 0;
}

nav::-webkit-scrollbar {
    display: none;
}

a {
    display: inline-block;
    width: 100px;
    color: cyan;
    padding: 5px;
    border-right: 1px solid cyan;

}

a.Selected {
    background: cyan;
    color: #003;
}

h2,
h3 {
    margin: 0;
    padding: 0;
    font-weight: normal;
    text-align: center;
}

h2 {
    font-size: 17px;
}

h3 {
    font-size: 15px;
}

section {
    flex-grow: 1;
    overflow-y: scroll;
    padding: 10px;
}
</style>
<script>
console.clear()
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { GUI } from "three/addons/libs/lil-gui.module.min.js";

const WIDTH = window.innerWidth
const HEIGHT = window.innerHeight
var canvas, gui
var ambientLight, directionalLight
const glbs = {}
export default {
    data() {
        return {
            WIDTH,
            HEIGHT,
            parts: [
                {
                    id: "zhuti", name: "主体", items: [
                        { id: "A", name: "主体" }
                    ]
                },
                {
                    id: "langan", name: "栏杆", items: [
                        { id: "A", name: "栏杆A" },
                        { id: "B", name: "栏杆B" },
                    ]
                },
                {
                    id: "fangding", name: "房顶", items: [
                        { id: "A", name: "房顶A" },
                        { id: "B", name: "房顶B" },
                    ]
                }
            ]
        }
    }, mounted() {
        canvas = this.$refs.canvas

        const renderer = new THREE.WebGLRenderer({ antialias: true, canvas });
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        //
        renderer.shadowMap.enabled = true;
        renderer.shadowMap.type = THREE.PCFSoftShadowMap;//吃性能
        ////////////////////////////////////////////////////////////////////
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x000000);

        const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
        camera.position.set(0, 20, 20);

        const controls = new OrbitControls(camera, renderer.domElement);
        controls.target.set(0, 5, 0);
        controls.update();
        //controls.enablePan = false;
        //controls.enagroundbleDamping = true;
        //////////////////////////////////////////////////////////////////////
        ambientLight = new THREE.AmbientLight("#ffffff", 1)
        scene.add(ambientLight)
        //
        directionalLight = new THREE.DirectionalLight("#ffffff", 1)
        directionalLight.position.set(-20, 20, 20)
        scene.add(directionalLight)
        directionalLight.castShadow = true
        directionalLight.shadow.intensity = 0.1;
        // 
        const directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight)
        scene.add(directionalLightHelper);
        ///////////////////////////////////////////////////////////////////////
        /* const textureLoader = new THREE.TextureLoader()
         function loadTexture(name) {
             return new Promise(resolve => {
                 const url = `${name}.jpg`
                 textureLoader.load(url, (texture) => {
                     texture.width = 2048
                     texture.height = 2048
                     texture.wrapS = THREE.RepeatWrapping;
                     texture.wrapT = THREE.RepeatWrapping;
                     resolve(texture);
                 });
             })
         }
         console.log(loadTexture)*/
        ////////////////////////////
        const dracoLoader = new DRACOLoader();
        dracoLoader.setDecoderPath('jsm/libs/draco/gltf/');

        const loader = new GLTFLoader();
        loader.setDRACOLoader(dracoLoader);
        const hourse_type = "jianshanju"
        const getKey = (part_index, item_index) => {
            const part = this.parts[part_index]
            const item = part.items[item_index]
            return `${part.id}_${item.id}`
        }
        const loadGLB = (part_index, item_index, isAnimate = false, isVisible = false) => {

            const promise = new Promise(resolve => {
                const key = getKey(part_index, item_index)
                loader.load(`1203/${hourse_type}_${key}.glb`, (gltf) => {
                    const fix_x = 0
                    const X = 0;
                    const glb = gltf.scene;
                    glb.traverse(obj => {
                        if (obj.isMesh) {
                            obj.receiveShadow = true
                            obj.castShadow = true
                        }
                    })
                    glb.position.set(fix_x + X, 0, 0);
                    if (isAnimate) {
                        animate()
                    }
                    glb.visible = isVisible
                    scene.add(glb);
                    glbs[key] = glb

                    //////////////////////////////
                    resolve(glb)
                }, undefined, function (e) {

                    console.error(e);

                });
            })

            this.parts[part_index].items[item_index].promise = promise
            return promise
        }
        console.log(loadGLB)

        var params = new function () {
            this.ambientLight_color = ambientLight.color
            this.ambientLight_intensity = ambientLight.intensity
            //
            this.directionalLight_color = directionalLight.color
            this.directionalLight_intensity = directionalLight.intensity
            const { x, y, z } = directionalLight.position
            this.directionalLight_x = x
            this.directionalLight_y = y
            this.directionalLight_z = z
            this.shadow = true
        }
        function addGUI() {


            gui = new GUI();
            //
            const ambientLightFolder = gui.addFolder('环境光');
            ambientLightFolder.addColor(params, "ambientLight_color").name('颜色').onChange(v => {
                ambientLight.color.set(v);
            });
            ambientLightFolder.add(params, "ambientLight_intensity", 0, 10).name('亮度').onChange(v => {
                ambientLight.intensity = v;
            });
            //
            const directionalLightFolder = gui.addFolder('平行光');
            directionalLightFolder.addColor(params, "directionalLight_color").name('颜色').onChange(v => {
                directionalLight.color.set(v);
            });
            directionalLightFolder.add(params, "directionalLight_intensity", 0, 10).name('亮度').onChange(v => {
                directionalLight.intensity = v;
            });
            directionalLightFolder.add(params, "directionalLight_x", -50, 50).name('位置X').onChange(v => {
                directionalLight.position.x = v;
            });
            directionalLightFolder.add(params, "directionalLight_y", -50, 50).name('位置Y').onChange(v => {
                directionalLight.position.y = v;
            });
            directionalLightFolder.add(params, "directionalLight_z", -50, 50).name('位置Z').onChange(v => {
                directionalLight.position.z = v;
            });
            directionalLightFolder.add(params, "shadow").name('阴影').onChange(v => {
                directionalLight.castShadow = v;
            });
            //   
            /*
          const blockFolder = gui.addFolder('砖块');
     
          blockFolder.addColor(params, "block_color", 0, 10).name('砖块-颜色').onChange(v => {
            block.material.color.set(v);
          });
          blockFolder.add(params, "block_map", ['文化石-01', '小青砖-01']).name('花纹').onChange(async v => {
              block.material.map = await loadTexture(v);
          });*/
        }
        /////////////////////////////////////////////
        window.onresize = function () {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize(window.innerWidth, window.innerHeight);

        };


        function animate() {
            requestAnimationFrame(animate)
            //  controls.update();

            renderer.render(scene, camera);

        }
        //////////////////////////
        const addGuiItem = (part_index, item_index) => {
            const part = this.parts[part_index]
            console.e
            if (part.id == "zhuti") {
                return
            }
            const key = getKey(part_index, item_index)
            part.selectedIndex = item_index
            params[key] = part.items[item_index].name
            settingFolder.add(params, key, part.items.map(item => item.name)).name(part.name).onChange(async (name) => {

                const key = getKey(part_index, part.selectedIndex)
                glbs[key].visible = false
                //
                const index = part.items.findIndex(item => item.name == name)
                part.selectedIndex = index
                part.items[index].promise.then((glb) => {
                    glb.visible = true
                })
            });
        }
        ////////////////////////////////////////////////////////////////////////////////////
        addGUI()
        //
        const settingFolder = gui.addFolder("选配");
        const promises = []
        this.parts.forEach((_, part_index) => {
            const item_index = 0
            const promise = loadGLB(part_index, item_index, true, true)
            addGuiItem(part_index, item_index)
            //
            promises.push(promise)
        })

        console.log(addGuiItem)
        Promise.all(promises).then(() => {
            console.error("已加载默认配置！")
            console.error("准备加载更多配置!")

            this.parts.forEach((part, part_index) => {
                part.items.forEach((_, item_index) => {
                    if (item_index == 0) {
                        return
                    }
                    const promise = loadGLB(part_index, item_index)
                    promises.push(promise)
                })
            })
        })
    }
}
</script>